<!-- 这是一个ViewUnit骨架容器，当视图单元包含异步加载内容时，将在这个中间层处理后渲染 -->
<!-- props数据的dls处理将在这里完成 -->
<script setup>
import {inject, onBeforeMount, onMounted, ref, watch} from "vue";
import ViewUnit from './ViewUnit.vue';
import {transVnode} from "./defaultRule/RenderRule.js"
import {v4 as uuidv4} from 'uuid'
import Sortable from "sortablejs"
import {waitValue} from "dlsjs"

const props = defineProps({
  /*这里的option是包含了dls的vnode配置*/
  vnode: {
    type: Object,
    default: () => ({})
  },
  dataScope: {
    type: Object,
    default: () => ({})
  },
  slotScope: {
    type: Object,
    default: () => ({})
  },
  funcScope: {
    type: Object,
    default: () => ({})
  },
  refScope: {
    type: Object,
    default: () => ({})
  }
})

/**
 * 捕捉自定义输出到顶层事件
 * @param e
 */
function catchEvent(e) {
  props.funcScope.emits('event', e)
}

/**
 * 拖拽添加元素
 * @param data
 */
function dropUnit(data) {
  if (!props.vnode.children) props.vnode.children = []
  props.vnode.children.push(data)
  refresh()
}

/**
 * 刷新页面
 */
const resultOption = ref()

function refresh() {
  resultOption.value = null
  setTimeout(() => {
    // resultOption.value = transVnode(props.vnode, props)
    resultOption.value = true
    initDrag()
  }, 0)
}

/**
 * 点击了视图,切换选中节点
 */
// const isActive = ref(false)
const selectVnodeId = inject('selectVnodeId')
function clickEViewer(event) {
  event.stopPropagation()
  selectVnodeId.value = props.vnode.uuid
  // isActive.value = true
  // const specialDiv = renderContent.value.$el
  // function unActive(event) {
  //   const clickedElement = event.target;
  //   // 如果点击的不是specialDiv自身
  //   if (clickedElement !== specialDiv) {
  //     isActive.value = false
  //     document.querySelector('.editor-area').removeEventListener('mousedown', unActive)
  //   }
  // }
  // setTimeout(() => {
  //   document.querySelector('.editor-area').addEventListener('mousedown', unActive)
  // }, 0)
}
function checkOut() {
  selectVnodeId.value = props.vnode.uuid
}

const mouseOverUidStack = inject('mouseOverUidStack')
const renderContent = ref()

/**
 * 删除此节点
 */
const hasDelete = ref(false)

function delThis() {
  delNode(props.vnode.uuid)
  hasDelete.value = true
  resultOption.value = null
}

const delNode = inject('delNode')
const copyNode = inject('copyNode')
const checkParentNode = inject('checkParentNode')

/**
 * 监听vnode更新时刷新
 */
watch(() => props.vnode.props, () => {
  refresh()
}, {deep: true})

watch(() => props.vnode.children?.length, () => {
  refresh()
}, {deep: true})

onBeforeMount(() => {
  // 渲染时生成uuid，用于此模板唯一标记
  if(!props.vnode.uuid) props.vnode.uuid = uuidv4()
  if(!props.vnode.props) props.vnode.props = { style: {} }
  refresh()
})

function changePermLevel(level, vnode) {
  vnode['@permLevel'] = level
  props.funcScope.emits('changePermLevel')
}

const permsMode = inject('permsMode')
const devMode = inject('devMode')
const readonlyMode = inject('readonlyMode')
defineExpose({refresh})


/**
 * 初始化拖拽
 */
async function initDrag() {
  if(!props.vnode.children?.length) return
  await waitValue(() => document.querySelector(`[uuid="${props.vnode.uuid}"] .drag-root`), 5000)
  new Sortable(document.querySelector(`[uuid="${props.vnode.uuid}"] .drag-root`),
    {
      handle: `.drag-handle-icon`,
      animation: 150,
      group: {
        name: 'lc-editor',
      },
      onEnd: (e) => {
        let tr = props.vnode.children.splice(e.oldIndex, 1)
        props.vnode.children.splice(e.newIndex, 0, tr[0])
      }
    }
  )
}

function copy(uuid) {
  copyNode(uuid)
}

onMounted(() => {
  initDrag()
})
</script>

<template>
  <template v-if="resultOption">
    <ViewUnit
      @mouseenter.self="(!vnode.hideMask || devMode) && mouseOverUidStack.unshift(vnode.uuid)"
      @mouseleave.self="(!vnode.hideMask || devMode) && mouseOverUidStack.shift()"
      ref="renderContent"
      :uuid="vnode.uuid"
      :key="vnode.uuid"
      :class="{
        'lc-editor-drag-item': true,
        over: mouseOverUidStack[0] === vnode.uuid,
        active: permsMode ? false : selectVnodeId === vnode.uuid
      }"
      :style="{ position: 'relative' }"
      :option="props.vnode"
      :refScope="refScope"
      :dataScope="dataScope"
      :funcScope="funcScope"
      :slotScope="slotScope"
      @event="catchEvent"
      @click="clickEViewer"
    >
    </ViewUnit>
    <teleport v-if="renderContent && !readonlyMode && (!vnode.hideMask || devMode)" :to="renderContent.$el">
      <template v-if="permsMode">
        <div class="mask forOver perms"></div>
        <div class="editor-mask-tag forOver perms row no-wrap">
          <q-btn-group>
            <q-btn dense :color="!vnode['@permLevel'] || vnode['@permLevel'] === 'edit' ? 'orange-8' : 'grey'" class="text-no-wrap" @click="changePermLevel('edit', vnode)" :style="{padding: '2px 5px'}" label="可编辑"></q-btn>
            <q-btn dense :color="vnode['@permLevel'] === 'readonly' ? 'orange-8' : 'grey'" class="text-no-wrap" @click="changePermLevel('readonly', vnode)" :style="{padding: '2px 5px'}" label="仅可见"></q-btn>
            <q-btn dense :color="vnode['@permLevel'] === 'hide' ? 'orange-8' : 'grey'" class="text-no-wrap" @click="changePermLevel('hide', vnode)" :style="{padding: '2px 5px'}" label="隐藏"></q-btn>
          </q-btn-group>
        </div>
      </template>
      <template v-else>
        <div class="mask"></div>
        <div class="editor-mask-tag forActive row no-wrap">
          <q-btn class="drag-handle-icon" dense color="primary" :style="{padding: '2px'}" icon="drag_handle" style="padding: 2px;" @click.stop="() => {}" @mousedown.stop="() => {}"></q-btn>
          <q-btn dense color="primary" :style="{padding: '0 8px', wordBreak: 'keep-all'}" :label="vnode.name_cn || vnode.type"></q-btn>
          <q-btn dense color="primary" :style="{padding: '2px'}" icon="arrow_outward" style="padding: 2px;" @click.stop="checkParentNode(vnode.uuid)"></q-btn>
          <q-btn dense color="primary" :style="{padding: '2px'}" icon="content_copy" style="padding: 2px;" @click.stop="copy(vnode.uuid)"></q-btn>
          <q-btn dense color="primary" :style="{padding: '2px'}" icon="delete_forever" style="padding: 2px;" @click="delThis"></q-btn>
        </div>
        <div class="mask forOver"></div>
        <div class="editor-mask-tag forOver row no-wrap">
          <q-btn dense color="secondary" @click="clickEViewer" :style="{padding: '0 8px', wordBreak: 'keep-all'}" :label="vnode.name_cn || vnode.type"></q-btn>
        </div>
      </template>
    </teleport>
  </template>
  <template v-else-if="hasDelete"></template>
  <div v-else>
    <q-inner-loading :showing="true"></q-inner-loading>
  </div>
</template>

<style scoped lang="scss">
.lc-editor-container-item {
  height: 100%;
  width: 100%;
  position: relative;
  margin: 1px;
}


/*蒙版标签*/
.editor-mask-tag {
  position: absolute;
  width: min-content;
  top: 0;
  right: 0;
  z-index: 2;
  //transform: translate(0, -100%);
  height: 25px;
  display: none;
}

/*蒙版与边框*/
.mask {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  background-color: #1976D211;
  outline: 2px dashed #1976D255;
  box-shadow: 0 0 1px 1px #C1001555;
  padding: 1px;
  box-sizing: border-box;
  display: none;
}

/*悬停显示*/
.lc-editor-drag-item:hover.over > .mask {
  display: block;
  z-index: 11;
}

.lc-editor-drag-item:hover.over:not(.active) > .editor-mask-tag.forOver {
  display: flex;
  z-index: 12;
}

/*选中显示*/
.lc-editor-drag-item.active > .mask {
  display: block;
  z-index: 9;
  pointer-events: none;
}

.lc-editor-drag-item.active > .editor-mask-tag.forActive {
  display: flex;
  z-index: 10;
}

/*防止丢失区块*/
.lc-editor-drag-item {
  min-height: 10px;
}

.mask.forOver.perms {
  pointer-events: all;
  background-color: #33333344;
}
.editor-mask-tag.forOver.perms {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}
</style>
